;***************************************** ;Project title: Snowman Controller * ;Version 1: 1.0 * ;Written By: MSH * ;Dated: 25/11/2019 * ;For PIC: PIC10F320T * ;Clock Freq: Internal (8 MHz) * ;***************************************** ; PROGRAM FUNCTION:Uses the 6pin 10F320 PICMCU (Peripheral Interface Controller Microprocessor Computational Unit) to operate ; a CD4020 ripple counter chip to control LEDs on a snowman. A light sensor limits its operation to night time through the ; use of a comparitor (compares sensor output to a voltage reference). List P=10F320 #include ; CONFIG ; __config 0xFDA0 __CONFIG _FOSC_INTOSC & _BOREN_OFF & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _LVP_ON & _LPBOR_OFF & _BORV_LO & _WRT_OFF ;============ ; Declarations: cycle2 equ 40 cycle8 equ 41 cycle16 equ 42 cycle80 equ 43 cycle128 equ 44 cycle160 equ 45 count195 equ 46 org 0x000 clrf PCLATH goto Start ;============ ; Subroutines: Init ; Intialisation subroutine: for configuring any registers clrf PORTA ; Clears all pin on Porta. All read '0'. movlw b'00001100' ; TRISA register is used to set whether the porta pins will function as inputs or movwf TRISA ; ouputs.For this application RA0 & RA1 are outputs and RA2 & RA3 are inputs. movlw b'00000000' ; All pins on porta set as digital I/O. movwf ANSELA ; movlw b'00001100' ; Enables weak pull-ups on pins RA2 & RA3 of Porta. movwf WPUA ; Pull-ups on RA1 & RA0 are disabled. movlw b'00000000' ; Disables all interrupts. movwf INTCON ; movlw b'00000100' ; Option register Setup: Weak pull-ups enabled by individual port latch values. movwf OPTION_REG ; TMR0 Prescaler enabled and set to 1:32. F=Fosc/4. movlw b'01100000' ; Internal Oscillator set to 8 MHz. movwf OSCCON ; Oscillator Control Register ;********************************Time Delay Register Initialisation*************************** call rstcycle2 ; resets cycle2 register. call rstcycle8 ; resets cycle4 register. call rstcycle16 ; resets cycle16 register. call rstcycle80 ; resets cycle80 register. call rstcycle128 ; resets cycle128 resister. call rstcycle160 ; resets cycle160 resister. movlw d'10' ; sets up count10 register by placing the number movwf count10 ; 10 into it. movlw d'195' ; sets up count195 register by placing the number movwf count195 ; 195 into it. retlw 0 ; Returns from subroutine with zero in the working register. ;****************************************************************************************** ;********************************Time Delay Sub-Routines*********************************** ;****************************************************************************************** half_sec clrf TMR0 ; resets TMR0. half_sec1 movf count195,w ; takes number out of count195 subwf TMR0,w ; Since TMR0 is Prescaled to 32, this will give a time ; of: 8MHz/4 = 2.0MHz/32 = 62500Hz per TMR0 clock. ; A count of 195 will give: 625Hz = 0.00313s. btfss STATUS,Z ; Bit-Test-File-skip(if)-set. TMR0 attempts to count from 0 to 255, when it reaches 195 the subtraction ; of 195 from TMR0 will result in 0. This sets the STATUS Registers Z (Zero) Flag; e.g: has a value of 1. ; When btfss tests the zero flag, it will skip the next instruction if it is set (=1). goto half_sec1 ; Loops to 'half_sec1'. decfsz cycle160 ; Decrements 'cycle160' and skips next instruction if zero. goto half_sec ; Loops to 'half_sec'. call rstcycle160 ; resets cycle160 register. retlw 0 ; Returns from subroutine with zero in the working register. quart_sec clrf TMR0 ; resets TMR0 to 0. quart_sec1 movf count195,w ; takes number out of count195 subwf TMR0,w ; Subtracts the number 195 from the value in TMR0. Since TMR0 is Prescaled ; to 32, this will give a timenof: 8MHz/4 = 2.0MHz/32 =62500Hz per TMR0 clock. ; A count of 195 will give: 321Hz = 0.00312s. btfss STATUS,Z ; Bit-Test-File-skip(if)-set. TMR0 attempts to count from 0 to 255, when it reaches 195 the subtraction ; of 195 from TMR0 will result in 0. This sets the STATUS Registers Z (Zero) Flag; e.g: has a value of 1. ; When btfss tests the zero flag, it will skip the next instruction if it is set (=1). goto quart_sec1 ; Loops to 'quart_sec1'. decfsz cycle80 ; Decrement(by 1)-file-skip(if)-Zero. Decrements 'cycle80' and skips next instruction if zero. 80*0.00313s = 0.25s goto quart_sec ; Loops to 'quart_sec'. call rstcycle80 ; resets cycle80 register. retlw 0 ; Returns from subroutine with zero in the working register. twent_sec clrf TMR0 ; resets TMR0. twent_sec1 movf count195,w ; takes number out of count195 subwf TMR0,w ; Since TMR0 is Prescaled to 32, this will give a time ; of: 8MHz/4 = 2.0MHz/32 = 62500Hz per TMR0 clock. ; A count of 195 will give: 321Hz = 0.00312s. btfss STATUS,Z ; Bit-Test-File-skip(if)-set. TMR0 attempts to count from 0 to 255, when it reaches 195 the subtraction ; of 195 from TMR0 will result in 0. This sets the STATUS Registers Z (Zero) Flag; e.g: has a value of 1. ; When btfss tests the zero flag, it will skip the next instruction if it is set (=1). goto twent_sec1 ; Loops to 'twent_sec1'. decfsz cycle16 ; Decrement(by 1)-file-skip(if)-Zero. Decrements 'cycle16' and skips next instruction if zero.16*0.00313s = 0.05s goto twent_sec ; Loops to 'twent_sec'. call rstcycle16 ; resets cycle16 register. retlw 0 ; Returns from subroutine with zero in the working register. fourt_sec clrf TMR0 ; resets TMR0. fourt_sec1 movf count195,w ; takes number out of count195 subwf TMR0,w ; Since TMR0 is Prescaled to 32, this will give a time ; of: 8MHz/4 = 2.0MHz/32 = 62500Hz per TMR0 clock. ; A count of 195 will give: 321Hz = 0.00312s. btfss STATUS,Z ; Bit-Test-File-skip(if)-set. TMR0 attempts to count from 0 to 255, when it reaches 195 the subtraction ; of 195 from TMR0 will result in 0. This sets the STATUS Registers Z (Zero) Flag; e.g: has a value of 1. ; When btfss tests the zero flag, it will skip the next instruction if it is set (=1). goto fourt_sec1 ; Loops to 'fourt_sec1'. decfsz cycle8 ; Decrement(by 1)-file-skip(if)-Zero. Decrements 'cycle8' and skips next instruction if zero.8*0.00313s = 0.025s goto fourt_sec ; Loops to 'fourt_sec'. call rstcycle8 ; resets cycle8 register. retlw 0 ; Returns from subroutine with zero in the working register. One60ith_sec clrf TMR0 ; resets TMR0. One60ith_sec1 movf count195,w ; takes number out of count195 subwf TMR0,w ; Since TMR0 is Prescaled to 32, this will give a time ; of: 8MHz/4 = 2.0MHz/32 = 62500Hz per TMR0 clock. ; A count of 195 will give: 321Hz = 0.00312s. btfss STATUS,Z ; Subtracts 195 from TMR0 and if the result is zero will set ; the zero flag. When btfss tests the zero flag, it skips ; the next instruction if set. goto One60ith_sec1 ; Loops to 'One60ith_sec1'. decfsz cycle2 ; Decrements 'cycle2' and skips next instruction if zero. goto One60ith_sec ; Loops to 'One60ith_sec'. call rstcycle2 ; resets cycle2 register. retlw 0 ; Returns from subroutine with zero in the working register. ;*************************************************************************************** ;******************************"Reset Time-Delay" Sub-routines************************** ;*************************************************************************************** rstcycle2 movlw d'2' ; places the number '2' into the cycle2 register. movwf cycle2 ; return ; returns from subroutine. rstcycle8 movlw d'8' ; places the number '8' into the cycle8 register. movwf cycle8 ; return rstcycle16 movlw d'16' ; places the number '16' into the cycle32 register. movwf cycle16 ; return ; returns from subroutine. rstcycle80 movlw d'80' ; places the number '80' into the cycle80 register. movwf cycle80 ; return ; returns from subroutine. rstcycle128 movlw d'128' ; places the number '128' into the cycle128 register. movwf cycle128 ; return ; returns from subroutine. rstcycle160 movlw d'160' ; places the number '160' into the cycle160 register. movwf cycle160 ; return ; returns from subroutine. ;------------------------------------------------------------------------------------------------- rst4020 movlw b'00000010' ; Puts a high (logic 1) voltage on the reset pin of CD4020 chip. movwf PORTA call twent_sec ; Calls subroutine which creates a 'twentieth of a second' time delay. movlw b'00000000' ; Puts a low (logic 0) voltage on the reset pin of CD4020 chip. movwf PORTA call twent_sec ; Calls subroutine which creates a 'twentieth of a second' time delay. retlw 0 RA0_high movlw b'00000001' ; Puts a high (logic 1) voltage on the clock pin of CD4020 chip. movwf PORTA ; retlw 0 RA0_low movlw b'00000000' ; Puts a low (logic 0) voltage on the clock pin of CD4020 chip. movwf PORTA ; retlw 0 ;------------------------------------------------------------------------------------------------ ; Program Start: Start call Init ; Initializes (Sets-up) registers relavant to the application. Main btfsc PORTA,2 ; goto PORTA3a ; goto PORTA3b ; PORTA3a btfsc PORTA,3 goto loop3 ; goto loop1 ; PORTA3b btfsc PORTA,3 goto loop2 ; goto loop4 ; loop1 call RA0_high ; Puts a high (logic 1) voltage on the clock pin of CD4020 chip. call twent_sec ; Calls subroutine which creates a 'twentieth of a second' time delay. call RA0_low ; Puts a low (logic 0) voltage on the clock pin of CD4020 chip. call twent_sec ; Calls subroutine which creates a 'twentieth of a second' time delay. decfsz cycle128 ; goto loop1 call rstcycle128 ; decfsz cycle8 ; goto loop1 call rstcycle8 ; resets cycle8 resister. call rst4020 ; Call subroutine to reset the 4020 binary counter. goto Main ; loops to Main. loop2 call RA0_high ; Puts a high (logic 1) voltage on the clock pin of CD4020 chip. call quart_sec ; Calls subroutine which creates a 'quarter of a second' time delay. call RA0_low ; Puts a low (logic 0) voltage on the clock pin of CD4020 chip. call quart_sec ; Calls subroutine which creates a 'quarter of a second' time delay. decfsz cycle128 ; goto loop2 call rstcycle128 ; decfsz cycle8 ; goto loop2 call rstcycle8 ; resets cycle8 resister. call rst4020 ; Call subroutine to reset the 4020 binary counter. goto Main ; loops to Main. loop3 call RA0_high ; Puts a high (logic 1) voltage on the clock pin of CD4020 chip. call fourt_sec ; Calls subroutine which creates a '40ith of a second' time delay. call RA0_low ; Puts a low (logic 0) voltage on the clock pin of CD4020 chip. call fourt_sec ; Calls subroutine which creates a '40ith of a second' time delay. decfsz cycle128 ; goto loop3 call rstcycle128 ; decfsz cycle8 ; goto loop3 call rstcycle8 ; resets cycle8 resister. call rst4020 ; Call subroutine to reset the 4020 binary counter. goto Main ; loops to Main. loop4 call RA0_high ; Puts a high (logic 1) voltage on the clock pin of CD4020 chip. call One60ith_sec ; Calls subroutine which creates a '160ith of a second' time delay. call RA0_low ; Puts a low (logic 0) voltage on the clock pin of CD4020 chip. call One60ith_sec ; Calls subroutine which creates a '160ith of a second' time delay. decfsz cycle128 ; goto loop4 call rstcycle128 ; decfsz cycle8 ; goto loop4 call rstcycle8 ; resets cycle8 resister. call rst4020 ; Call subroutine to reset the 4020 binary counter. goto Main ; loops to Main. END